package modular02.work02;


import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author ASUS
 * @date 2020/7/17 18:30
 * @description
 */
public class Chessboard {

    private String[][] chessboard; //构建棋盘的二维数组

    private int chessboardNum;//棋盘编号

    private int defaultSize = 10; //棋盘默认大小

    private int countPlayer = 0;//在线玩家数 可限制进入棋盘的人数

    private Scanner sc;

//    private ThreadLocal<Integer> winner = new ThreadLocal<>();//赢的队伍

    private AtomicInteger winner;//赢的队伍



    /**
     * 构造方法 用户传入棋盘的二维大小，用于构建棋盘的二维数组
     *
     * @param size 棋盘大小
     */
    public Chessboard(int size) {
        chessboard = new String[size][size];
        chessboard[0][0] = " ";
        for (int i = 1; i < chessboard.length; i++) {
            int temp = i + 87; //todo 用于构建棋盘位置坐标时，大于等于10时 转化为英文字母使用 通过ASCII码强转char实现
            if (i < 10) {
                chessboard[i][0] = i + "";
            } else {
                chessboard[i][0] = String.valueOf((char) temp);
            }
            if (i < 10) {
                chessboard[0][i] = i + "";

            } else {
                chessboard[0][i] = String.valueOf((char) temp);
            }
        }
        for (int i = 1; i < chessboard.length; i++) {
            for (int j = 1; j < chessboard[i].length; j++) {
                chessboard[i][j] = "*";
            }
        }
    }

    public Chessboard() {
        chessboard = new String[defaultSize][defaultSize];
        chessboard[0][0] = " ";
        for (int i = 1; i < chessboard.length; i++) {
            int temp = i + 87;
            if (i < 10) {
                chessboard[i][0] = i + "";
            } else {
                chessboard[i][0] = String.valueOf((char) temp);
            }
            if (i < 10) {
                chessboard[0][i] = i + "";

            } else {
                chessboard[0][i] = String.valueOf((char) temp);
            }
        }
        for (int i = 1; i < chessboard.length; i++) {
            for (int j = 1; j < chessboard[i].length; j++) {
                chessboard[i][j] = "*";
            }
        }
    }

    public AtomicInteger getWinner() {
        return winner;
    }

    public void setWinner(AtomicInteger winner) {
        this.winner = winner;
    }

    /**
     * 打印棋盘
     */
    public void printChessManual() {

        for (int j = 0; j < chessboard[0].length; j++) {
            System.out.print(chessboard[0][j] + " ");
        }

        for (int i = 1; i < chessboard.length; i++) {
            System.out.println();

            for (int j = 0; j < chessboard[i].length; j++) {
                System.out.print(chessboard[i][j] + " ");
            }
        }
        System.out.println();

    }

    public int joinChessboard() {
        switch (countPlayer) {
            case 0:
                countPlayer++;
                System.out.println("加入棋盘");//todo 可加入棋盘编号 标记玩家正在进行的棋局
                return 1;
            case 1:
                countPlayer++;
                System.out.println("加入棋盘");//todo 可加入棋盘编号 标记玩家正在进行的棋局
                return 2;
            default:
                System.out.println("人满了");
                return 0;
        }
    }


    /**
     * @param team 黑棋为1 白棋为2
     * @return
     */
    public boolean move(int team) {
        synchronized (this) {

            if (winner != null) {
                System.out.println(winner.get());
                return false;
            }
            sc = new Scanner(System.in);
            boolean flag = true;
            while (true) {
                if (countPlayer < 2) {
                    System.out.println("一个人怎么下棋啊");
                    return false;
                }
                if (team == 1) {
                    System.out.println("黑棋回合");
                } else if (team == 2) {
                    System.out.println("白棋回合");
                }
                System.out.println("请输入下棋的坐标如括号中格式（x y）");
                String strx = sc.next();
                String stry = sc.next();
                int x = 0, y = 0;//最终落子的二维数组下标x，y轴的下标
                //判断x轴是否越界
                for (int i = 1; i < chessboard.length; i++) {
                    if (strx.equals(chessboard[0][i])) {
                        x = i;
                        flag = true;
                        break;
                    } else {
                        flag = false;
                    }
                }
                if (!flag) {
                    System.out.println("输入有误 重新输入x");
                    continue;
                }
                //判断y轴是否越界
                for (int j = 1; j < chessboard[0].length; j++) {
                    if (stry.equals(chessboard[j][0])) {
                        y = j;
                        flag = true;
                        break;
                    } else {
                        flag = false;
                    }
                }
                if (!flag) {
                    System.out.println("输入有误 重新输入y");
                    continue;
                }
                if (chessboard[x][y].equals("*")) {
                    if (1 == team) {
                        chessboard[x][y] = "●";
                        if (this.findWinner(team, x, y)) {
                            winner = new AtomicInteger(1);
                        }
                    } else if (2 == team) {
                        chessboard[x][y] = "O";
                        if (this.findWinner(team, x, y)) {
                            winner = new AtomicInteger(2);
                        }
                    }
                } else {
                    System.out.println("不是空位");
                    continue;
                }
                try {
                    this.printChessManual();
                    this.notify();
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("执行结束");
                return true;
            }
        }

    }

    /**
     * 获胜条件判断
     *
     * @param team
     * @param x    当前落子的 chessboard[x][?]
     * @param y    当前落子的 chessboard[?][j]
     * @return true为胜利 false为输
     */
    private boolean findWinner(int team, int x, int y) {
        if (winByAcross(team, x, y)) {
            return true;
        } else if (winByFvertical(team, x, y)) {
            return true;
        } else if (winByDiagonal(team, x, y)) {
            return true;
        }
        return false;
    }


    private boolean winByAcross(int team, int x, int y) {
        if (1 == team) {
            int count = 1;
            //向右匹配
            for (int j = y + 1; j < chessboard[x].length; j++) {
                if (chessboard[x][j].equals("●")) {
                    count++;
                    System.out.println("count ="+count);
                    if (count >= 5) {
                        return true;
                    }
                } else {
                    break;
                }
            }
            //向左匹配
            for (int j = y - 1;j>0; j--) {
                if (chessboard[x][j].equals("●")) {
                    count++;
                    System.out.println("count ="+count);
                    if (count >= 5) {
                        return true;
                    }
                } else {
                    break;
                }
            }

        } else if (2 == team) {
            int count = 1;

            for (int j = y + 1; j < chessboard[x].length; j++) {
                if (chessboard[x][j].equals("O")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                } else {
                    break;
                }
            }
            for (int j = y - 1; j > 0; j--) {
                if (chessboard[x][j].equals("O")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                } else {
                    break;
                }
            }
        }
        return false;
    }

    /**
     * 竖直判读输赢
     * @param team
     * @param x
     * @param y
     * @return
     */
    private boolean winByFvertical(int team, int x, int y) {
        if (team == 1) {
            int count = 1;

            for (int i = x + 1; i < chessboard.length; i++) {
                if (chessboard[i][y].equals("●")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                } else {
                    break;
                }
            }
            for (int i = x - 1; i > 0; i--) {
                if (chessboard[i][y].equals("●")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                } else {
                    break;
                }
            }

        } else if (team == 2) {
            int count = 1;

            for (int i = y + 1; i < chessboard.length; i++) {
                if (chessboard[i][y].equals("O")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                } else {
                    break;
                }
            }
            for (int i = x - 1; i >= 0; i--) {
                if (chessboard[i][y].equals("O")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                } else {
                    break;
                }
            }

        }
        return false;
    }

    /**
     * 斜线判断输赢
     * @param team 队伍信息
     * @param x    落子的 arr[x][]
     * @param y    落子的 arr[][y]
     * @return
     */
    private boolean winByDiagonal(int team, int x, int y) {
        if (team == 1) {
            int i = 1+x, j = 1+y;
            int count = 1;
            while (i < chessboard.length && j < chessboard[i].length) {
                if (chessboard[i][j].equals("●")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                    i++;
                    j++;//二维数组两个下标都+1 ,相当于以斜线方式右移一位
                } else {
                    break;
                }
            }
            //向左匹配
            i = x-1;
            j = y-1;
            while (i > 0 && j > 0) {
                if (chessboard[i][j].equals("●")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                    i--;
                    j--;//二维数组两个下标都+1 ,相当于以斜线方式右移一位
                } else {
                    break;
                }
            }

        } else if (team == 2) {
            int i = 1+x, j = 1+y;
            int count = 1;
            while (i < chessboard.length && j < chessboard[i].length) {
                if (chessboard[i][j].equals("O")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                    i++;
                    j++;//二维数组两个下标都+1 ,相当于以斜线方式右移一位
                } else {
                    break;
                }
            }
            i = x-1;
            j = y-1;
            while (i > 0 && j > 0) {
                if (chessboard[i][j].equals("O")) {
                    count++;
                    if (count >= 5) {
                        return true;
                    }
                    i--;
                    j--;//二维数组两个下标都+1 ,相当于以斜线方式左移一位
                } else {
                    break;
                }
            }
        }

        return false;
    }
}
